#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <vector>

const int thread_num = 5;
using namespace std;

class Task
{
public:
    Task(){}

    void setData(int x, int y)
    {
        datax = x;
        datay = y;
    }

    int Execute()
    {
        return datay + datax;
    }

    ~Task() {}

private:
    int datax;
    int datay;
};

class ThreadData : public Task
{
public:
    ThreadData(int x, int y, const string &threadName)
        : _threadName(threadName)
    {
        _t.setData(x, y);
    }

    string threadName()
    {
        return _threadName;
    }

    int run()
    {
        return _t.Execute();
    }

private:
    string _threadName;
    Task _t;
};

class Result
{
public:
    Result() {}
    ~Result() {}
    void setResult(int result, const string &threadname)
    {
        _result = result;
        _threadname = threadname;
    }

    void Print()
    {
        cout << _threadname << " : " << _result << endl;
    }

private:
    int _result;
    string _threadname;
};

void *handlerTask(void *agrs)
{
    ThreadData *td = static_cast<ThreadData *>(agrs);

    string name = td->threadName();
    Result *res = new Result();
    int result = td->run();
    res->setResult(result,name);

    cout << name << "run result" << result << endl;
    delete td;

    sleep(1);
    return res;

    // const char *threadName = static_cast<char*>(agrs);
    // while(true)
    // {
    //     cout<<"I am "<<threadName<<endl;
    //     sleep(1);
    // }
    // delete []threadName;

    // return nullptr;
}

// 创建多线程
// 线程创建时传参和返回值，可以传递基本信息，也可以传递自定义对象
int main()
{
    vector<pthread_t> threads;
    for (int i = 0; i < thread_num; i++)
    {
        char threadName[64];
        snprintf(threadName, 64, "Thread-%d", i + 1);
        ThreadData *td = new ThreadData(3, 5, threadName);

        pthread_t tid;
        pthread_create(&tid, nullptr, handlerTask, td);

        threads.push_back(tid);
        sleep(1);
    }

    vector<Result *> result_set;
    void *res = nullptr;
    for (auto &tid : threads)
    {
        pthread_join(tid, &res);
        result_set.push_back((Result *)res);
    }

    for (auto &res : result_set)
    {
        res->Print();
        delete res;
    }

    return 0;
}

// 线程退出
// 1.代码跑完，结果正确
// 2.代码跑完，结果错误
// 3.出现异常
// void *newthreadrun(void *agrs)
// {
//     int cur = 5;
//     while (cur)
//     {
//         cout << "new thread, pid: " << getpid() << "  newthread id: " << pthread_self() << endl;
//         cout << endl;
//         sleep(2);
//         cur--;
//     }

//     //exit();不能使用exit，这是用于终止进程的函数
//     //pthread_exit((void*)1);
//     return (void*) 1;
// }

// // 主线程退出，进程也就退出，所有线程全部退出
// // 1、一般情况下，main线程需要最后结束
// // 2、线程也需要被wait回收，否则会产生类似内存泄漏的问题
// int main()
// {
//     // 1.id创建新线程
//     pthread_t tid;
//     pthread_create(&tid, nullptr, newthreadrun, nullptr);

//     //退出线程
//     pthread_cancel(tid);

//     // 3.进程阻塞等待
//     int n = pthread_join(tid, nullptr);
//     cout << "main thread quit,pid: " << getpid() << "  main id: " << pthread_self() << endl;

//     // 2.主线程，新线程，谁先运行？不确定，由调度器确定
//     //  int cur = 5;
//     //  while(cur)
//     //  {
//     //      cout<<"main thread,pid: "<<getpid()<<"  main id: "<<pthread_self()<<endl;
//     //      cout<<endl;
//     //      sleep(2);
//     //      cur--;
//     //  }
//     return 0;
// }